﻿using System;
using System.ComponentModel;
using System.Reactive.Subjects;
using System.Windows.Input;
using Betfair.Api.Types;
using Bull.Core;

namespace Bull.Plugins.Login.ViewModels {
    public sealed class LoginViewModel : ContentViewModel, IDataErrorInfo {
        private readonly IOpenFileDialog _openFileDialog;
        
        private string _password;
        private string _username;

        private ICommand _showDialogCommand;
        private ICommand _loginCommand;
        private ICommand _cancelCommand;

        private string _applicationKey;
        private string _certificatePassword;
        private string _errorMessage;

        public LoginViewModel(string username, string applicationKey, string certificatePath, IOpenFileDialog openFileDialog)
        {
            Username = username;
            ApplicationKey = applicationKey;
            CertificatePath = certificatePath;
            _openFileDialog = openFileDialog;
        }

        public string Username {
            get { return _username; }
            set {
                _username = value;
                OnPropertyChanged("Username");
            }
        }

        public string Password {
            get { return _password; }
            set {
                _password = value;
                OnPropertyChanged("Password");
            }
        }

        public string ApplicationKey {
            get { return _applicationKey; }
            set {
                _applicationKey = value;
                OnPropertyChanged("ApplicationKey");
            }
        }

        public string CertificatePath
        {
            get { return _certificatePath; }
            private set
            {
                _certificatePath = value;
                OnPropertyChanged("CertificatePath");
            }
        }

        public string CertificatePassword {
            get { return _certificatePassword; }
            set {
                _certificatePassword = value;
                OnPropertyChanged("CertificatePassword");
            }
        }

        public string ErrorMessage {
            get { return _errorMessage; }
            private set {
                _errorMessage = value;
                OnPropertyChanged("ErrorMessage");
            }
        }

        public ICommand ShowDialogCommand {
            get {
                return _showDialogCommand ?? (_showDialogCommand = new DelegateCommand(() => {
                    _openFileDialog.ShowDialog("Personal Information Exchange (*.pfx;*.p12) | *.pfx;*.p12");
                    CertificatePath = _openFileDialog.FileName;
                }));
            }
        }

        public ICommand LoginCommand {
            get {
                return _loginCommand ?? (_loginCommand = new DelegateCommand(async () => {
                    var session = await IoC.Container.BetfairProxy.Login(Username, Password, ApplicationKey, CertificatePath, CertificatePassword);
                    ErrorMessage = string.Empty;
                    if(session.ResponseType == ResponseType.ERROR) {
                        ErrorMessage = session.Error;
                    }
                    else {
                        _subject.OnNext(true);
                        _subject.OnCompleted();
                    }
                }, IsValid));
            }
        }

        public ICommand CancelCommand { get
        {
            return _cancelCommand ?? (_cancelCommand = new DelegateCommand(() =>
            {
                Username = string.Empty;
                Password = string.Empty;
                ApplicationKey = string.Empty;
                CertificatePath = string.Empty;
                CertificatePassword = string.Empty;
            }));
        } }

        public string this[string columnName] {
            get {
                if(columnName == "Username")
                    return string.IsNullOrWhiteSpace(Username) ? "Please insert a username" : null;
                if(columnName == "Password")
                    return string.IsNullOrWhiteSpace(Password) ? "Please insert the password" : null;
                if(columnName == "ApplicationKey")
                    return string.IsNullOrWhiteSpace(ApplicationKey) ? "Please insert the application key" : null;
                if(columnName == "CertificatePath")
                    return string.IsNullOrWhiteSpace(CertificatePath) ? "Please select the certificate path" : null;
                if(columnName == "CertificatePassword")
                    return string.IsNullOrWhiteSpace(CertificatePassword) ? "Please insert the certificate password" : null;

                return null;
            }
        }

        public string Error { get { return null; } }

        private bool IsValid() {
            return !string.IsNullOrWhiteSpace(Username) && !string.IsNullOrWhiteSpace(Password) &&
                   !string.IsNullOrWhiteSpace(ApplicationKey) && !string.IsNullOrWhiteSpace(CertificatePath) &&
                   !string.IsNullOrWhiteSpace(CertificatePassword);

        }

        private readonly ISubject<bool> _subject = new Subject<bool>();
        private string _certificatePath;

        public IObservable<bool> OnLogin()
        {
            return _subject;
        }
    }
}
